﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Authorization.Roles;
using Abp.Authorization.Users;
using Abp.Dependency;
using Abp.Domain.Entities;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.MultiTenancy;
using XHD.WXZJ.Departments;

namespace XHD.WXZJ.Posts
{
    public class PostStore<TTenant, TDepartment, TUser,TPost> :
        ITransientDependency
        where TTenant : AbpTenant<TTenant, TUser>
        where TDepartment : AbpDepartment<TTenant, TUser>
        where TUser : AbpUser<TTenant, TUser>
        where TPost : Posts<TTenant, TDepartment, TUser>
    {
        private readonly IRepository<TUser, long> _userRepository;
        private readonly IRepository<TPost, int> _postRepository;
        private readonly IRepository<PostUser, int> _postUserRepository;
        private readonly IUnitOfWorkManager _unitOfWorkManager;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userRepository"></param>
        /// <param name="postRepository"></param>
        /// <param name="departmentRepository"></param>
        /// <param name="postUserRepository"></param>
        /// <param name="unitOfWorkManager"></param>
        public PostStore(IRepository<TUser, long> userRepository,
            IRepository<TPost, int> postRepository,
            IRepository<PostUser, int> postUserRepository,
            IUnitOfWorkManager unitOfWorkManager)
        {
            _postRepository = postRepository;
           _postUserRepository = postUserRepository;
            _unitOfWorkManager = unitOfWorkManager;
            _userRepository = userRepository;
        }

        public virtual IQueryable<TPost> Posts
        {
            get { return _postRepository.GetAll(); }
        }

        public virtual async Task CreateAsync(TPost post)
        {
            await _postRepository.InsertAsync(post);
        }

        public virtual async Task UpdateAsync(TPost post)
        {
            await _postRepository.UpdateAsync(post);
        }

        public virtual async Task DeleteAsync(TPost post)
        {
            await _postUserRepository.DeleteAsync(ur => ur.PostId == post.Id);
            await _postRepository.DeleteAsync(post);
        }

        public virtual async Task<TPost> FindByIdAsync(int postId)
        {
            return await _postRepository.FirstOrDefaultAsync(postId);
        }

        public virtual async Task<TPost> FindByNameAsync(string postName)
        {
            return await _postRepository.FirstOrDefaultAsync(
                post => post.Name == postName
                );
        }

        public virtual async Task<TPost> FindByDisplayNameAsync(string displayName)
        {
            return await _postRepository.FirstOrDefaultAsync(
                post => post.DisplayName == displayName
                );
        }
        /// <summary>
        /// 新增用户到岗位
        /// </summary>
        /// <param name="user"></param>
        /// <param name="postName"></param>
        /// <returns></returns>

        public virtual async Task AddToPostAsync(TUser user, string postName)
        {
            var post = await _postRepository.SingleAsync(p => p.Name == postName);
            await _postUserRepository.InsertAsync(
                new PostUser
                {
                    UserId = user.Id,
                    PostId = post.Id
                });
        }

        /// <summary>
        /// 重载新增用户到岗位
        /// </summary>
        /// <param name="user"></param>
        /// <param name="post"></param>
        /// <returns></returns>
        public virtual async Task AddToPostAsync(TUser user, TPost post)
        {
            
            await _postUserRepository.InsertAsync(
                new PostUser
                {
                    UserId = user.Id,
                    PostId = post.Id
                });
        }

        /// <summary>
        /// 重载添加多个用户到岗位
        /// </summary>
        /// <param name="users"></param>
        /// <param name="post"></param>
        /// <returns></returns>
        public virtual async Task AddToPostAsync(List<TUser> users, TPost post)
        {
        
            foreach (var user in users)
            {
                var postUser = new PostUser
                {
                    PostId = post.Id,
                    UserId = user.Id
                };
              
                await _postUserRepository.InsertAsync(postUser);
            }

            
        }

        /// <summary>
        /// 将人员从岗位移除
        /// </summary>
        /// <param name="user"></param>
        /// <param name="postName"></param>
        /// <returns></returns>
        public virtual async Task RemoveFromAsync(TUser user, string postName)
        {
            var post = await _postRepository.SingleAsync(p => p.Name == postName);

            var postUser = _postUserRepository.FirstOrDefault(pu => pu.PostId == post.Id && pu.UserId == user.Id);
            if (postUser == null)
            {
                return;
            }
            await _postUserRepository.DeleteAsync(postUser);
        }
        /// <summary>
        /// 重载将人员从岗位移除
        /// </summary>
        /// <param name="users"></param>
        /// <param name="postName"></param>
        /// <returns></returns>
        public virtual async Task RemoveFromAsync(List<TUser> users, string postName)
        {
            var post = await _postRepository.SingleAsync(p => p.Name == postName);
            foreach (var oUser in users)
            {
                var postUser = _postUserRepository.FirstOrDefault(pu => pu.PostId == post.Id && pu.UserId == oUser.Id);
                if (postUser == null)
                {
                    return;
                }
                await _postUserRepository.DeleteAsync(postUser);
            }
        }
        /// <summary>
        /// 获取岗位下所有人员名称
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        public virtual Task<IList<string>> GetUsersAsync(TPost post)
        {
            //TODO: This is not implemented as async.

            var userNames = _postUserRepository.Query(postUsers => (from postUser in postUsers
                                                                    join user in _userRepository.GetAll() on postUser.UserId equals user.Id
                                                                    where postUser.PostId == post.Id
                                                                    select user.Name).ToList());
            return Task.FromResult<IList<string>>(userNames);
        }
        /// <summary>
        /// 获取岗位下满所有的用户信息
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        public virtual Task<IList<TUser>> GetUsersEntityAsync(TPost post)
        {
            //TODO: This is not implemented as async.

            var users= _postUserRepository.Query(postUsers => (from postUser in postUsers
                                                                    join user in _userRepository.GetAll() on postUser.UserId equals user.Id
                                                                    where postUser.PostId == post.Id
                                                                    select user).ToList());
            return Task.FromResult<IList<TUser>>(users);
        }



    }
}
